
import gridmapper.server.planner.*;
import gridmapper.*;

import java.awt.*; 
import java.awt.event.*;
import javax.swing.*;


public class GridMapperGUI extends JFrame implements ActionListener
{
	private static final long serialVersionUID = -8745299598700482748L;
	
	private JButton[][] buttons;
	
	int r1_dir = RobotHeading.NORTH;
	int gridX = 4;
	int gridY = 6;
    GridPlanner roomba = new GridPlanner(gridX, gridY, new Point(0,0), r1_dir);
    JPanel pane = new JPanel(new BorderLayout());
	TextField textbox1 = new TextField();
	TextField textbox2 = new TextField();
	TextField textbox3 = new TextField();
	TextField textbox4 = new TextField();
	Label x1 = new Label();
	Label y1 = new Label();
	Label x2 = new Label();
	Label y2 = new Label();
	Label macModeLabel = new Label();
	boolean macMode = false;
	boolean addingObject = false;
	JButton addObject = new JButton();
	JButton roombaButton = new JButton();
	JButton clearButton = new JButton();
	JButton northButton = new JButton();
	JButton southButton = new JButton();
	JButton eastButton = new JButton();
	JButton westButton = new JButton();
	JButton toggleButton = new JButton();
	boolean r2_visible = false;

  	GridMapperGUI() // the frame constructor method
  	{
  		super("GridMapper"); setBounds(100,100,600,600);
  		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  		Container con = this.getContentPane(); // inherit main frame
  		setVisible(true); // display this frame
  		Dimension size = con.getSize();
  		String osName= System.getProperty("os.name");
		if (osName.contains("mac") || osName.contains("OSx") || osName.contains("OS x"))
			macMode = true;
		
		if(macMode) 
		{
			try 
			{
				UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
			} 
			catch (Exception e) 
			{
				e.printStackTrace();
			}
		}

  		buttons = new JButton[roomba.gridY][roomba.gridX]; //array of buttons
  		int Xsize = (size.width) / roomba.gridX;
  		int Ysize = (size.height-50) / roomba.gridY;
  		
  		for (int i = 0; i < roomba.gridX; i++)
  		{
  			for (int j = 0; j < roomba.gridY; j++)
  			{
  				JButton button = new JButton();
  				button.setSize(Xsize, Ysize);
  				button.setLocation(i * Xsize, (j * Ysize) + 50);
  				button.setBackground(Color.LIGHT_GRAY);
  				button.addActionListener(this);
  				if (roomba.cells[j][i] == CellState.scannedOccupied)
  					button.setBackground(Color.yellow);
  				button.setVisible(true);
  				buttons[j][i] = button;
  				pane.add(button);
  			}
  		}
  		pane.setFont(new Font("Dialog", 1, 10));

  		textbox1.setLocation(25, 5);
  		textbox1.setSize(25, 20);
  		textbox1.setText(0+"");
  		
  		textbox2.setLocation(75, 5);
  		textbox2.setSize(25, 20);
  		textbox2.setText(0+"");
  		
  		
  		x1.setLocation(5, 5);
  		x1.setText("X:");
  		x1.setSize(20,20);
  		x1.setForeground(Color.white);
  		
  		y1.setLocation(55, 5);
  		y1.setText("Y:");
  		y1.setSize(20,20);
  		y1.setForeground(Color.white);
  		
  		textbox3.setLocation(size.width-(55+25), 5);
  		textbox3.setSize(25, 20);
  		textbox3.setText(3+"");
  		
  		textbox4.setLocation(size.width-(5+25), 5);
  		textbox4.setSize(25, 20);
  		textbox4.setText(2+"");
  		
  		x2.setLocation(size.width-(55+25+20), 5);
  		x2.setText("X:");
  		x2.setSize(20,20);
  		x2.setForeground(Color.white);
  		
  		y2.setLocation(size.width-(5+25+20), 5);
  		y2.setText("Y:");
  		y2.setSize(20,20);
  		y2.setForeground(Color.white);
  		
  		
  		
  		northButton.setText("N");
  		northButton.setSize(50,20);
  		northButton.setLocation(size.width/2 - northButton.getSize().width/2, 25);
  		northButton.addActionListener(this); //add on click event
  		
  		southButton.setText("S");
  		southButton.setSize(50,20);
  		southButton.setLocation(size.width/2 - southButton.getSize().width/2, 5);
  		southButton.addActionListener(this); //add on click event
  		
  		eastButton.setText("E");
  		eastButton.setSize(50,20);
  		eastButton.setLocation(southButton.getLocation().x - eastButton.getSize().width, 25);
  		eastButton.addActionListener(this); //add on click event
  		
  		westButton.setText("W");
  		westButton.setSize(50,20);
  		westButton.setLocation(southButton.getLocation().x + westButton.getSize().width, 25);
  		westButton.addActionListener(this); //add on click event
  		
  		
  		roombaButton.setText("run");
  		roombaButton.setSize(75,20);
  		roombaButton.addActionListener(this); //add on click event
  		roombaButton.setLocation(y1.getLocation().x + roombaButton.getSize().width, 5);
  		
  		clearButton.setText("clear");
  		clearButton.setSize(75,20);
  		clearButton.addActionListener(this); //add on click event
  		clearButton.setLocation(y1.getLocation().x + roombaButton.getSize().width, 25);

  		addObject.setText("add object");
  		addObject.setSize(100,20);
  		addObject.setLocation(x2.getLocation().x - x2.getSize().width - addObject.getSize().width, 5);
  		addObject.addActionListener(this); //add on click event
  		
  		
  		toggleButton.setLocation(size.width - (115), 5);
  		toggleButton.setText("+ Add R2");
  		toggleButton.setSize(110,20);
  		toggleButton.addActionListener(this); //add on click event

  		macModeLabel.setLocation(5, 25);
  		macModeLabel.setText("Is Mac? : " + macMode);
  		macModeLabel.setSize(100,20);
  		macModeLabel.setForeground(Color.white);
  		
  		pane.setBackground(Color.gray);

  		pane.add(x1);
  		pane.add(y1);
  		pane.add(x2);
  		pane.add(y2);
  		pane.add(textbox1);
  		pane.add(textbox2);
  		pane.add(textbox3);
  		pane.add(textbox4);
  		pane.add(macModeLabel);
  		pane.add(clearButton);
  		pane.add(addObject);
  		pane.add(roombaButton);
  		pane.add(northButton);
  		pane.add(southButton);
  		pane.add(eastButton);
  		pane.add(westButton);
  		pane.add(toggleButton);
  		pane.add(new Label());
  		setR2vis(r2_visible);

  		con.add(pane); // add the panel to frame
  		
        roombaInit();
        redrawRoomba();
        
  		 int Xvalue1 = Integer.parseInt(textbox1.getText());
         int Yvalue1 = Integer.parseInt(textbox2.getText());
         
         buttons[Yvalue1][Xvalue1].setBackground(Color.green);
         buttons[Yvalue1][Xvalue1].setText("Start");
         if (r2_visible)
         {
             int Xvalue2 = Integer.parseInt(textbox3.getText());
             int Yvalue2 = Integer.parseInt(textbox4.getText());
        	 buttons[Yvalue2][Xvalue2].setBackground(Color.orange);
	         buttons[Yvalue2][Xvalue2].setText("Start");
         }
         
  }
  	
  	public void updateCells(int x, int y, CellState state)
  	{
  		

  		switch (state) 
  		{
			case open:
		  		buttons[y][x].setBackground(Color.LIGHT_GRAY);
		  		buttons[y][x].setOpaque(true);

		  		
				break;
			case explored:
				buttons[y][x].setBackground(Color.BLUE);
				buttons[y][x].setOpaque(true);
				break;
			case scannedOccupied:
				buttons[y][x].setBackground(Color.YELLOW);
				buttons[y][x].setOpaque(true);
				break;
			case scannedOpen:
	      	  	buttons[y][x].setBackground(Color.red);
	      	  	buttons[y][x].setOpaque(true);
				break;
		}
  	
  	}
  	private void setR2vis(boolean visible)
  	{
  		textbox3.setVisible(visible);
  		textbox4.setVisible(visible);
  		x2.setVisible(visible);
  		y2.setVisible(visible);
  		if (visible)
  		{
  			toggleButton.setText("- Remove R2");
  	  		toggleButton.setLocation(this.getContentPane().getSize().width - (124), 30);
  	  		toggleButton.setSize(120,20);
  			
  		}
		else
		{
			toggleButton.setLocation(this.getContentPane().getSize().width - (105), 5);
	  		toggleButton.setText("+ Add R2");
	  		toggleButton.setSize(100,20);
		}
  		r2_visible = visible;
  	
  	}
	public void roombaInit()
	{
		int Xvalue = Integer.parseInt(textbox1.getText());
        int Yvalue = Integer.parseInt(textbox2.getText());
		roomba = new GridPlanner(gridX,gridY, new Point(Xvalue,Yvalue), r1_dir);
        roomba.changeCellState(roomba.Robot1_Location, CellState.explored, false);
        roomba.markScannedCells(roomba.Robot1_Location.x, roomba.Robot1_Location.y, roomba.Robot1_Direction);
        //roomba.run();
        roomba.moves = null; 
		redrawRoomba();

	}
	public void clear()
	{
		if (roomba !=null)
		{
			for (int x = 0; x < roomba.gridX; x++)
			{
				for (int y = 0; y < roomba.gridY; y++)
				{
					if (roomba.cells[y][x] != CellState.scannedOccupied)
						roomba.changeCellState(x,y,CellState.open, true);
					
				}	
				
			}
			
		}
		int Xvalue1 = Integer.parseInt(textbox1.getText());
        int Yvalue1 = Integer.parseInt(textbox2.getText());
        roomba.Robot1_Location = new Point(Xvalue1, Yvalue1);
        roomba.changeCellState(roomba.Robot1_Location, CellState.explored, false);
        roomba.markScannedCells(roomba.Robot1_Location.x, roomba.Robot1_Location.y, roomba.Robot1_Direction);
        redrawRoomba();
	}
	public void roombaNext()
	{
		if (roomba.moves != null)
		{
			Point last = roomba.moves.get(roomba.moves.size() -1);
			if (roomba.cells[last.y][last.x] != CellState.open) //if the last cell has been used, replan
			{
				roomba.run();
			}
		}
		if (!roomba.travelling || roomba.moves == null)
			roomba.run();
		if (roomba.moves == null || roomba.moves.size() == 0)
		{
			String newLine = System.getProperty("line.separator");
			JOptionPane.showMessageDialog(this.getContentPane(), "no moves in queue." + newLine + "cells open = " + roomba.areCellsOpen());
		}
		else
		{
			repaint();
			/*try { Thread.sleep(100); }
			catch (InterruptedException e) { System.out.println(e); }
*/
			roomba.readNextMove(true);
			redrawRoomba();

			//roombaNext();


		}	
	}
  	public void actionPerformed(ActionEvent e)
  	{
         JButton buttonPressed = (JButton) e.getSource();
         
         if (buttonPressed == northButton)
         {
        	 r1_dir = RobotHeading.NORTH;
        	 roombaInit();
         }
         else if (buttonPressed == southButton)
         {
        	 r1_dir = RobotHeading.SOUTH;
        	 roombaInit();
         }
         else if (buttonPressed == eastButton)
         {
        	 r1_dir = RobotHeading.EAST;
        	 roombaInit();
         }
         else if (buttonPressed == westButton)
         {
        	 r1_dir = RobotHeading.WEST;
        	 roombaInit();
         }
         else if (buttonPressed == clearButton)
         {
        	 clear();
         }
         else if (buttonPressed == addObject)
         {
        	 addingObject = !addingObject;
        	 if (addingObject)
        		 addObject.setText("stop adding");
        	 else 
        		 addObject.setText("add object");
         }
         else if (buttonPressed == roombaButton)
         {
        	 roombaNext();
         }
         else if (buttonPressed == toggleButton)
         {
        	 setR2vis(!r2_visible);
         }
         else
         {
        	 int setX = Integer.parseInt(textbox1.getText());
             int setY = Integer.parseInt(textbox2.getText());
             int Xvalue2 = Integer.parseInt(textbox3.getText());
             int Yvalue2 = Integer.parseInt(textbox4.getText());
             
	         for (int x = 0; x < roomba.gridX; x++)
	         {
	             for (int y = 0; y < roomba.gridY; y++)
	             {
	                 if (buttonPressed == buttons[y][x])
	                 {
	                	 if (addingObject)
	                	 {
	                		 if(roomba.cells[y][x] == CellState.scannedOccupied)
	                		 {
	                			 roomba.changeCellState(x, y, CellState.open, true);
	                		 }
	                		 else
	                			 roomba.changeCellState(x, y, CellState.scannedOccupied, true);
	                	 }
	                	 else
	                	 {
		                	 if ((x != Xvalue2 || y != Yvalue2) || !r2_visible)
		                	 {
		                		 setX = x;
		                		 setY = y;
			                     textbox1.setText(x+"");
			                     textbox2.setText(y+"");
			                     break;
		                	 }
	                	 }
	                 }
	             }
	
	         }
	         if (!addingObject)
	        	 roombaInit();
	         redrawRoomba();
        	 buttons[setY][setX].setText("Start");
        	 if (r2_visible)
        		 buttons[Yvalue2][Xvalue2].setText("Start");


         }



 }	
  	

  private void redrawRoomba()
  {
	  int Xvalue1 = Integer.parseInt(textbox1.getText());
      int Yvalue1 = Integer.parseInt(textbox2.getText());
      for (int i = 0; i < roomba.gridX; i++)
      {
          for (int j = 0; j < roomba.gridY; j++)
          {
        	  buttons[j][i].setBackground(Color.LIGHT_GRAY);
              buttons[j][i].setText("");// i + "," + j;
              updateCells(i, j, roomba.cells[j][i]);
          }
      }
      buttons[Yvalue1][Xvalue1].setBackground(Color.green);
      buttons[Yvalue1][Xvalue1].setText("Start");
      if (r2_visible)
      {
          int Xvalue2 = Integer.parseInt(textbox3.getText());
          int Yvalue2 = Integer.parseInt(textbox4.getText());
    	  buttons[Yvalue2][Xvalue2].setBackground(Color.orange);
    	  buttons[Yvalue2][Xvalue2].setText("Start");
      }

      buttons[roomba.Robot1_Location.y][roomba.Robot1_Location.x].setBackground(Color.pink);

  }
  
  public static void main(String args[]) {
	  new GridMapperGUI();
	  }
  
}